#include "../../core/pch.h"

/**
 * INFO TABLE routines.
 */

int IT_exists(char* ip, int port, int pid, int worker_port, struct info_table* table_ptr)
{
	int i;
	for (i = 0; i < table_ptr->count; i++)
	{
		if (table_ptr->pid[i] == pid && (strcmp(table_ptr->ip[i], ip) == 0))
			return 1;
	}
	return 0;
}

void IT_make_dead(char* ip, int port, struct info_table* table_ptr)
{
	int i;
	for (i = 0; i < table_ptr->count; i++)
	{
		if (table_ptr->port[i] == port && (strcmp(table_ptr->ip[i], ip) == 0))
		{
			table_ptr->alive[i] = 0;
		}
	}
}

void IT_add(char *ip, int port, int pid, int worker_port, struct info_table* table_ptr)
{
	if (IT_exists(ip, port, pid, worker_port, table_ptr)) 
		return;

	int idx = table_ptr->count;
	strcpy(table_ptr->ip[idx], ip);
	table_ptr->port[idx] = port;
	table_ptr->worker_port[idx] = worker_port;
	table_ptr->pid[idx] = pid;
	table_ptr->idle[idx] = 1;
	table_ptr->alive[idx] = 1;
	table_ptr->count++;
}

void IT_print(struct info_table* table_ptr)
{
	system("clear");
	int i;
	printf("IP               | ");
	printf("Port       | ");
	printf("Idle | ");
	printf("Alive\n");
	for (i = 0; i < table_ptr->count; i++)
	{
		printf("%-16s | %.10d | %4s | %3s\n", table_ptr->ip[i], table_ptr->port[i],
			table_ptr->idle[i] == 0 ? "Work" : "Free", 
			table_ptr->alive[i] == 1 ? "Yes" : "Noo");
	}
	printf("NUMBER = %d\n", table_ptr->NUMBER);
}

void IT_make_idle(char* ip, int port, int pid, struct info_table* table_ptr)
{
	int i;
	for (i = 0; i < table_ptr->count; i++)
	{
		if ((strcmp(table_ptr->ip[i], ip) == 0 && table_ptr->port[i] == port) ||
			table_ptr->pid[i] == pid)
			table_ptr->idle[i] = 1;
	}
}

int IT_exists(char *ip, int port, struct info_table* table_ptr)
{
	// not implemented yet
	return 0;
}


/**
 * Primes file routines. Opening - FILE *file = fopen("../../data/primes", "r+b");
 */

void PF_set_sent(int number, FILE* file) //PF - Primes File
{
   struct prime_str prime;
   fseek(file, sizeof(struct prime_str)*(number - 1), 0);
   fread(&prime, sizeof prime, 1, file);
   prime.sent = '1';
   fseek(file, sizeof(struct prime_str)*(number - 1), 0);
   fwrite(&prime, sizeof prime, 1, file);
}

void PF_set_not_sent(int number, FILE* file)
{
   struct prime_str prime;
   fseek(file, sizeof(struct prime_str)*(number - 1), 0);
   fread(&prime, sizeof prime, 1, file);
   prime.sent = '0';
   fseek(file, sizeof(struct prime_str)*(number - 1), 0);
   fwrite(&prime, sizeof prime, 1, file);
}

void PF_set_not_received(int number, FILE* file)
{
   struct prime_str prime;
   fseek(file, sizeof(struct prime_str)*(number - 1), 0);
   fread(&prime, sizeof prime, 1, file);
   prime.received = '0';
   fseek(file, sizeof(struct prime_str)*(number - 1), 0);
   fwrite(&prime, sizeof prime, 1, file);
}

void PF_set_received_not_divisor(int number, FILE* file)
{
   struct prime_str prime;
   fseek(file, sizeof(struct prime_str)*(number - 1), 0);
   fread(&prime, sizeof prime, 1, file);
   prime.received = '1';
   fseek(file, sizeof(struct prime_str)*(number - 1), 0);
   fwrite(&prime, sizeof prime, 1, file);
}

void PF_set_received_divisor(int number, FILE* file)
{
   struct prime_str prime;
   fseek(file, sizeof(struct prime_str)*(number - 1), 0);
   fread(&prime, sizeof prime, 1, file);
   prime.received = '2';
   fseek(file, sizeof(struct prime_str)*(number - 1), 0);
   fwrite(&prime, sizeof prime, 1, file);
}

struct prime_str PF_get_first_not_sent(FILE* file)
{
   struct prime_str prime;
   fseek(file, 0, 0);
   while (fread(&prime, sizeof prime, 1, file) == 1)
   {
      if (prime.sent == '0')
      {
         return prime;
      }
   }
}

void PF_clear_primes(FILE* file)
{
	struct prime_str prime;
	int i = 0;
	
	fseek(file, -sizeof(struct prime_str), 2);
	fread(&prime, sizeof prime, 1, file);
	int max = prime.number;
	
	fseek(file, 0, 0);
	while (i < max)
	{
      fseek(file, sizeof(struct prime_str)*i, 0);
      fread(&prime, sizeof prime, 1, file);
      prime.sent = '0';
      prime.received = '0';
      fseek(file, sizeof(struct prime_str)*i, 0);
      fwrite(&prime, sizeof prime, 1, file);
		i++;
	}
}
